;;; init-isearch.el --- Configuration for isearch -*- lexical-binding: t -*-
;;; Commentary:
;;; Code:

(with-eval-after-load 'isearch
  (setq isearch-lazy-count t)
  (setq lazy-highlight-initial-delay 0.75)
  (setq isearch-lax-whitespace t)
  (setq search-whitespace-regexp ".*")
  (setq isearch-regexp-lax-whitespace nil)
  (setq isearch-allow-motion t)

  (defun isearch-yank-symbol ()
    "*Put symbol at current point into search string."
    (interactive)
    (let ((sym (thing-at-point 'symbol)))
      (if sym
          (progn
            (setq isearch-regexp t
                  isearch-string (concat "\\_<" (regexp-quote sym) "\\_>")
                  isearch-message (mapconcat 'isearch-text-char-description isearch-string "")
                  isearch-yank-flag t))
        (ding)))
    (isearch-search-and-update))

  (defun sanityinc/isearch-exit-other-end ()
    "Exit isearch, but at the other end of the search string.
This is useful when followed by an immediate kill."
    (interactive)
    (isearch-exit)
    (goto-char isearch-other-end))

  (defun prot/isearch-abort ()
    "Remove non-matching `isearch' input, reverting to previous
successful search and continuing with the search.

This is a modified variant of the original `isearch-abort',
mapped to C-g which will remove the failed match if any and only
afterwards exit the search altogether."
    (interactive)
    (discard-input)
    (while (or (not isearch-success) isearch-error)
      (isearch-pop-state))
    (isearch-update))

  (define-key isearch-mode-map (kbd "TAB") #'isearch-complete)
  (define-key isearch-mode-map (kbd "C-.") #'prot/isearch-abort)
  (define-key isearch-mode-map (kbd "C-M-w") #'isearch-yank-symbol)
  (define-key isearch-mode-map (kbd "C-M-e") #'isearch-forward-symbol-at-point)
  ;; (define-key isearch-mode-map [(control return)] #'sanityinc/isearch-exit-other-end)
  ;; DEL during isearch should edit the search string, not jump back to the previousresult
  (define-key isearch-mode-map [remap isearch-delete-char] #'isearch-del-char)
  (define-key isearch-mode-map (kbd "C-c C-o") #'isearch-occur)
  (define-key isearch-mode-map (kbd "M-e") #'consult-isearch-history)
  (define-key isearch-mode-map (kbd "C-;") 'avy-isearch)

  (defun consult-line-from-isearch ()
  "Invoke `consult-line' from isearch."
  (interactive)
  (let ((search-nonincremental-instead nil)
        (query (if isearch-regexp
                   isearch-string
                 (regexp-quote isearch-string))))
    (isearch-exit)
    (consult-line query)))

  (define-key isearch-mode-map (kbd "<C-return>") #'consult-line-from-isearch))

(provide 'init-isearch)
;;; init-isearch.el ends here
